﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace ExceptionParser
{
    /// <summary>
    /// Custom event arguments for a custom event.
    /// </summary>
    public class ParserEventArgs
    {
        public ParserEventArgs(int t, int c) { Try_s = t; Catch_s = c; }
        public int Try_s { get; set; }
        public int Catch_s { get; set; }
    }

    public class ExceptionParser
    {
        /// <summary>
        /// Delegate, which contains custom event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void ParserEventHandler(ParserEventArgs e);
        /// <summary>
        /// Custom event.
        /// </summary>
        public event ParserEventHandler Over;
      
        /// <summary>
        /// Indicates, if the examined character is a part of a string.
        /// </summary>
        private bool isString;
        public bool IsString
        {
            get { return isString; }
            set { isString = value; }
        }

        /// <summary>
        /// Indicates, if the examined character is a part of a comment.
        /// </summary>
        private bool isComment;
        public bool IsComment
        {
            get { return isComment; }
            set { isComment = value; }
        }

        /// <summary>
        /// Char array, containing characters from the examined string.
        /// </summary>
        private char[] splitString;
        public char[] SplitString
        {
            get { return splitString; }
            set { splitString = value; }
        }

        /// <summary>
        /// Number of try blocks, found in program text.
        /// </summary>
        private int try_s;
        public int Try_s
        {
            get { return try_s; }
            set { try_s = value; }
        }

        /// <summary>
        /// Number of catch blocks, found in program text.
        /// </summary>
        private static int catch_s;
        public static int Catch_s
        {
            get { return catch_s; }
            set { catch_s = value; }
        } 
        
        /// <summary>
        /// Counts the number of Try and Catch blocks.
        /// </summary>
        /// <param name="inputText">Text of C# program.</param>
        /// <returns>Text with deleted comments and masked string values.</returns>
        public void ExceptionSearch(string[] inputText)
        {
            
            IsString = false;
            IsComment = false;
            SplitString = null;
            Try_s = 0;
            Catch_s = 0;
            for (int i = 0; i < inputText.Length; i++)
            {
                //Masking string values
                #region Deleting Strings

                if (inputText[i].IndexOf(('\\').ToString() + "\"") != -1)
                    inputText[i] = inputText[i].Replace(('\\').ToString() + "\"", "x");
                if (inputText[i].IndexOf("'\"'") != -1)
                    inputText[i] = inputText[i].Replace("'\"'", "x");
                if (inputText[i].IndexOf("'\\\\\'") != -1)
                    inputText[i] = inputText[i].Replace("'\\\\\'", "x");

                SplitString = inputText[i].ToCharArray();

                for (int k = 0; k < SplitString.Length; k++)
                {
                    if (SplitString[k] == '"')
                    {
                        IsString = !IsString;
                    }
                    else if (IsString == true) SplitString[k] = 'x';
                    inputText[i] = new string(SplitString);
                }

                #endregion

                //Deleting comments
                #region Deleting Comments
                if (IsComment == true)
                {
                    if (inputText[i].IndexOf("*/") != -1)
                    {
                        inputText[i] = inputText[i].Remove(0, inputText[i].IndexOf("*/") + 2);
                        IsComment = false;
                    }
                    else inputText[i] = "";
                }

                if (inputText[i].IndexOf("//") != -1)
                {
                    inputText[i] = inputText[i].Remove(inputText[i].IndexOf("//"));
                }

                while (true)
                {
                    if (inputText[i].IndexOf("/*") != -1)
                    {
                        if (inputText[i].IndexOf("*/") != -1)
                            inputText[i] = inputText[i].Remove(inputText[i].IndexOf("/*"), inputText[i].IndexOf("*/") - inputText[i].IndexOf("/*") + 2);
                        else
                        {
                            inputText[i] = inputText[i].Remove(inputText[i].IndexOf("/*"));
                            IsComment = true;
                        }
                    }
                    else break;
                }
                #endregion

                //Searching Try and Catch blocks
                Try_s += new Regex("try").Matches(inputText[i]).Count;
                Catch_s += new Regex("catch").Matches(inputText[i]).Count;
            }
            
            if(Over!=null)
                 Over(new ParserEventArgs(Try_s,Catch_s));
        }
    }
}
